/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 文件名：	ProcessDBAppender.java
 * 模块说明：	
 * 修改历史：
 * 2007-4-12 - lxm - 创建。
 */
package com.hd123.rumba.log;

import java.util.Date;
import java.util.HashMap;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;

import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.runtime.NamingMgr;

/**日志添加器，提供将后端处理日志写入到数据库中。
 * @author lxm
 *
 */
public class ProcessDBAppender extends AppenderSkeleton {
  
  /** 消息前缀 */
  public static final String PREFIX_MESSAGE = "_BackProcess_";
  /** 键名：所属域uuid */
  public static final String KEY_DOMAIN_UUID = "domain";
  /** 键名：处理过程实例的类名 */
  public static final String KEY_PROCESS_CLASSNAME = "className";
  /** 键名：处理过程实例的Uuid */
  public static final String KEY_PROCESS_UUID = "uuid";
  /** 键名：处理过程的标题 */
  public static final String KEY_PROCESS_CAPTION = "caption";
  /** 键名：处理过程实例的拥有者键值1 */
  public static final String KEY_OWNERKEY_1 = "ownerKey1";
  /** 键名：处理过程实例的拥有者键值2 */
  public static final String KEY_OWNERKEY_2 = "ownerKey2";
  /** 键名：处理过程实例的拥有者键值3 */
  public static final String KEY_OWNERKEY_3 = "ownerKey3";
  /** 键名：处理过程实例的拥有者键值4 */
  public static final String KEY_OWNERKEY_4 = "ownerKey4";
  /** 键名：处理过程实例的开始时间*/
  public static final String KEY_STARTTIME = "startTime";
  /** 键名：操作人 */
  public static final String KEY_OPERATOR = "operator";
  /** 键名：消息 */
  public static final String KEY_MESSAGE = "message";

  @Override
  protected void append(LoggingEvent event) {
    HashMap msgs = decodeMessage(event.getMessage().toString());
    if (!msgs.containsKey(PREFIX_MESSAGE))
      return;
    
    try {
      writeToDB(msgs, event);
    } catch (Exception e) {
      this.errorHandler.error("将日志信息写入数据库时发生错误。", e, -1, event);
    }
  }

  @Override
  public boolean requiresLayout() {
    return false;
  }

  @Override
  public void close() {
    if (this.closed)
      return;
    this.closed = true;
  }
  
  private IProcessLogMgr logMgr = null;
  private IDomainMgr domainMgr = null;
  
  private IProcessLogMgr getLogMgr() throws BusinessException {
    if (logMgr == null)
      logMgr = (IProcessLogMgr) NamingMgr.getInstance().lookupMgr(IProcessLogMgr.class);
    return logMgr;
  }
  
  private IDomainMgr getDomainMgr() throws BusinessException {
    if (domainMgr == null)
      domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    return domainMgr;
  }
  
  private HashMap decodeMessage(String message) {
    HashMap map = new HashMap();
    String[] msgs = message.split("#");
    for (int i = 0; i < msgs.length; i++) {
      String[] kv = msgs[i].split("=", 2);
      String key = kv[0];
      String value = kv.length > 1 ? kv[1] : null;
      map.put(key, value);
    }
    return map;
  }
  
  private void writeToDB(HashMap msgs, LoggingEvent event) throws Exception {
    IProcessLog log = getLogMgr().createLog();
    
    String domainUuid = (String) msgs.get(KEY_DOMAIN_UUID);
    IDomain domain = getDomainMgr().getDomain(domainUuid);
    log.setDomain(domain);
    
    log.setProcessClassName((String) msgs.get(KEY_PROCESS_CLASSNAME));
    String processUuid = (String) msgs.get(KEY_PROCESS_UUID);
    log.setProcessUuid(processUuid);
    log.setProcessCaption((String) msgs.get(KEY_PROCESS_CAPTION));
    
    String ownerKey1 = (String) msgs.get(KEY_OWNERKEY_1);
    if (ownerKey1 != null)
      log.setOwnerKey1(ownerKey1);
    String ownerKey2 = (String) msgs.get(KEY_OWNERKEY_2);
    if (ownerKey2 != null)
      log.setOwnerKey1(ownerKey2);
    String ownerKey3 = (String) msgs.get(KEY_OWNERKEY_3);
    if (ownerKey3 != null)
      log.setOwnerKey1(ownerKey3);
    String ownerKey4 = (String) msgs.get(KEY_OWNERKEY_4);
    if (ownerKey4 != null)
      log.setOwnerKey1(ownerKey4);
    
    int maxItemNo = getLogMgr().getMaxItemNo(processUuid);
    log.setItemNo(maxItemNo + 1);
    
    String startTimeStr = (String) msgs.get(KEY_STARTTIME);
    Date startTime = new Date();
    if (startTimeStr != null)
      startTime = new Date((new Long(startTimeStr)).longValue());
    log.setStartTime(startTime);
    
    log.setOperator((String) msgs.get(KEY_OPERATOR));
    log.setTime(new Date(event.timeStamp));
    log.setType(new Integer(event.getLevel().toInt()));
    
    StringBuffer sb = new StringBuffer();
    String message = (String) msgs.get(KEY_MESSAGE);
    if (message != null)
      sb.append(message);
    String[] tms = event.getThrowableStrRep();
    if (tms != null && tms.length > 0)
      for (int i = 0; i < tms.length; i++) {
        if (sb.length() > 0)
          sb.append("\n");
        sb.append(tms[i]);
      }
    log.setMessage(sb.toString());
    
    getLogMgr().saveT(log);
  }
}
